package com.igoal.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.igoal.entity.ComponentEnum;
import com.igoal.entity.DataStatus;
import com.igoal.entity.UserCheer;
import com.igoal.web.Constants;

@Repository("userCheerDAO")
public class UserCheerDAOImpl extends GenericDaoHibernate<UserCheer, Long>
		implements UserCheerDAO {
	public UserCheerDAOImpl() {
		super(UserCheer.class);
	}

	public boolean isCheerThis(Long userId, ComponentEnum component, Long componentId) {
		return findByInfomration(userId, component, componentId) != null;
	}

	public int countCheerThisComponent(ComponentEnum component, Long componentId) {
		DetachedCriteria dc = DetachedCriteria.forClass(UserCheer.class);
		dc.add(Restrictions.eq("component", component));
		dc.add(Restrictions.eq("componentId", componentId));
		
		List<UserCheer> result = findByCriteria(dc);
		
		return result.size();
	}

	public UserCheer findByInfomration(Long userId, ComponentEnum component,
			Long componentId) {
		DetachedCriteria dc = DetachedCriteria.forClass(UserCheer.class);
		dc.add(Restrictions.eq("user.id", userId));
		dc.add(Restrictions.eq("component", component));
		dc.add(Restrictions.eq("componentId", componentId));
		dc.add(Restrictions.eq("status", DataStatus.USING));
		
		List<UserCheer> result = findByCriteria(dc);
		
		//Assert.isTrue(result.size() <= 1);
		if(result.size() > 1){
			log.error("UserId["+userId+"] has liked ["+component+"-"+componentId+"] more than one.");
		}
		
		if(result.size() > 0)
			return result.get(0);
		
		return null;
	}

	public List<UserCheer> getUserCheereddThisComponent(ComponentEnum component, Long componentId) {
		DetachedCriteria dc = DetachedCriteria.forClass(UserCheer.class);
		dc.add(Restrictions.eq("component", component));
		dc.add(Restrictions.eq("componentId", componentId));

		List<UserCheer> result = findByCriteria(dc);
		return result;
	}

	public List<UserCheer> getRandomeCheerList(Long userId, ComponentEnum component, Long componentId) {
		DetachedCriteria dc = DetachedCriteria.forClass(UserCheer.class);
		List<UserCheer> result = new ArrayList<UserCheer>();
		List<UserCheer> randomList;

		// check if current user likes this component
		UserCheer currentLike = findByInfomration(userId, component, componentId);

		// get random users
		dc.add(Restrictions.eq("component", component));
		dc.add(Restrictions.eq("componentId", componentId));

		int getSize = Constants.RANDOM_LIKE_LIST_SIZE;
		if (currentLike != null) {
			result.add(currentLike);
			getSize--;
			dc.add(Restrictions.ne("user.id", userId));
		}
		getByStatus(dc, DataStatus.USING);
		getRandomEntities(dc);
		randomList = findByCriteria(dc, 0, getSize);

		if (randomList != null) {
			result.addAll(randomList);
		}

		return result;
	}

	public List<UserCheer> getUserCheeredThisComponent(ComponentEnum component, Long componentId,
			int pageNumber) {
		DetachedCriteria dc = DetachedCriteria.forClass(UserCheer.class);
		dc.add(Restrictions.eq("component", component));
		dc.add(Restrictions.eq("componentId", componentId));
		getByStatus(dc, DataStatus.USING);
		// TODO should use alphabet sort
		dc.addOrder(Order.desc("updateDate"));

		List<UserCheer> result = findByCriteria(dc, Constants.LIKE_LIST_PAGE_SIZE
				* (pageNumber - 1), Constants.LIKE_LIST_PAGE_SIZE);
		return result;
	}
}
